package controller;

import dao.SystemSettingsDAO;
import java.sql.SQLException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.List;

/**
 * 系统设置控制器
 */
public class SystemSettingsController {
    private SystemSettingsDAO systemSettingsDAO;
    private Map<String, String> settingsCache;
    private long lastCacheUpdate = 0;
    private static final long CACHE_TIMEOUT = 5 * 60 * 1000; // 5分钟缓存

    public SystemSettingsController() {
        this.systemSettingsDAO = new SystemSettingsDAO();
        this.settingsCache = new HashMap<>();
        try {
            systemSettingsDAO.initializeDefaultSettings();
            refreshCache();
        } catch (SQLException e) {
            e.printStackTrace();
            // 如果初始化失败，使用硬编码默认值
            loadHardcodedDefaults();
        }
    }

    /**
     * 获取所有系统设置
     */
    public Map<String, String> getAllSettings() {
        try {
            if (shouldRefreshCache()) {
                refreshCache();
            }
            return new HashMap<>(settingsCache);
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap<>(settingsCache); // 返回缓存的值
        }
    }

    /**
     * 获取单个设置值
     */
    public String getSetting(String key) {
        try {
            if (shouldRefreshCache()) {
                refreshCache();
            }
            return settingsCache.get(key);
        } catch (Exception e) {
            e.printStackTrace();
            return settingsCache.get(key); // 返回缓存的值
        }
    }

    /**
     * 获取整型设置值
     */
    public int getIntSetting(String key, int defaultValue) {
        String value = getSetting(key);
        if (value != null) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                System.err.println("无效的整型设置值: " + key + " = " + value);
            }
        }
        return defaultValue;
    }

    /**
     * 获取布尔型设置值
     */
    public boolean getBooleanSetting(String key, boolean defaultValue) {
        String value = getSetting(key);
        if (value != null) {
            return "true".equalsIgnoreCase(value) || "1".equals(value);
        }
        return defaultValue;
    }

    /**
     * 获取时间设置值
     */
    public LocalTime getTimeSetting(String key, LocalTime defaultValue) {
        String value = getSetting(key);
        if (value != null) {
            try {
                return LocalTime.parse(value, DateTimeFormatter.ofPattern("HH:mm"));
            } catch (Exception e) {
                System.err.println("无效的时间设置值: " + key + " = " + value);
            }
        }
        return defaultValue;
    }

    /**
     * 更新单个设置
     */
    public boolean updateSetting(String key, String value, int adminUserId, String reason) {
        try {
            boolean success = systemSettingsDAO.updateSetting(key, value, adminUserId, reason);
            if (success) {
                // 更新缓存
                settingsCache.put(key, value);
            }
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("更新设置失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新设置
     */
    public boolean updateMultipleSettings(Map<String, String> settings, int adminUserId, String reason) {
        try {
            boolean success = systemSettingsDAO.updateMultipleSettings(settings, adminUserId, reason);
            if (success) {
                // 更新缓存
                settingsCache.putAll(settings);
            }
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("批量更新设置失败: " + e.getMessage());
        }
    }

    /**
     * 保存预约相关设置
     */
    public boolean saveReservationSettings(int maxDays, int maxHours, boolean allowCancel,
            int cancelDeadline, int adminUserId) {
        Map<String, String> settings = new HashMap<>();
        settings.put("MAX_RESERVATION_DAYS", String.valueOf(maxDays));
        settings.put("MAX_RESERVATION_HOURS", String.valueOf(maxHours));
        settings.put("ALLOW_CANCEL_RESERVATION", String.valueOf(allowCancel));
        settings.put("CANCEL_DEADLINE_HOURS", String.valueOf(cancelDeadline));

        return updateMultipleSettings(settings, adminUserId, "更新预约设置");
    }

    /**
     * 保存时间段设置
     */
    public boolean saveTimeSlotSettings(LocalTime morningStart, LocalTime morningEnd,
            LocalTime afternoonStart, LocalTime afternoonEnd,
            LocalTime eveningStart, LocalTime eveningEnd,
            int adminUserId) {
        Map<String, String> settings = new HashMap<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");

        settings.put("MORNING_START_TIME", morningStart.format(formatter));
        settings.put("MORNING_END_TIME", morningEnd.format(formatter));
        settings.put("AFTERNOON_START_TIME", afternoonStart.format(formatter));
        settings.put("AFTERNOON_END_TIME", afternoonEnd.format(formatter));
        settings.put("EVENING_START_TIME", eveningStart.format(formatter));
        settings.put("EVENING_END_TIME", eveningEnd.format(formatter));

        return updateMultipleSettings(settings, adminUserId, "更新时间段设置");
    }

    /**
     * 保存系统公告
     */
    public boolean saveSystemNotice(String notice, int adminUserId) {
        return updateSetting("SYSTEM_NOTICE", notice, adminUserId, "更新系统公告");
    }

    /**
     * 重置为默认设置
     */
    public boolean resetToDefaults(int adminUserId) {
        try {
            boolean success = systemSettingsDAO.resetToDefaults(adminUserId);
            if (success) {
                refreshCache(); // 重新加载缓存
            }
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("重置设置失败: " + e.getMessage());
        }
    }

    /**
     * 获取设置变更日志
     */
    public List<Map<String, Object>> getSettingsLog(int limit) {
        try {
            return systemSettingsDAO.getSettingsLog(limit);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("获取设置日志失败: " + e.getMessage());
        }
    }

    /**
     * 验证设置值的有效性
     */
    public boolean validateSettings(Map<String, String> settings) {
        try {
            // 验证预约设置
            if (settings.containsKey("MAX_RESERVATION_DAYS")) {
                int days = Integer.parseInt(settings.get("MAX_RESERVATION_DAYS"));
                if (days < 1 || days > 30) {
                    throw new IllegalArgumentException("最大预约天数必须在1-30之间");
                }
            }

            if (settings.containsKey("MAX_RESERVATION_HOURS")) {
                int hours = Integer.parseInt(settings.get("MAX_RESERVATION_HOURS"));
                if (hours < 1 || hours > 12) {
                    throw new IllegalArgumentException("最大预约时长必须在1-12小时之间");
                }
            }

            if (settings.containsKey("CANCEL_DEADLINE_HOURS")) {
                int deadline = Integer.parseInt(settings.get("CANCEL_DEADLINE_HOURS"));
                if (deadline < 0 || deadline > 24) {
                    throw new IllegalArgumentException("取消截止时间必须在0-24小时之间");
                }
            }

            // 验证时间设置
            String[] timeKeys = { "MORNING_START_TIME", "MORNING_END_TIME",
                    "AFTERNOON_START_TIME", "AFTERNOON_END_TIME",
                    "EVENING_START_TIME", "EVENING_END_TIME" };

            for (String key : timeKeys) {
                if (settings.containsKey(key)) {
                    LocalTime.parse(settings.get(key), DateTimeFormatter.ofPattern("HH:mm"));
                }
            }

            // 验证时间段逻辑
            if (settings.containsKey("MORNING_START_TIME") && settings.containsKey("MORNING_END_TIME")) {
                LocalTime start = LocalTime.parse(settings.get("MORNING_START_TIME"));
                LocalTime end = LocalTime.parse(settings.get("MORNING_END_TIME"));
                if (!start.isBefore(end)) {
                    throw new IllegalArgumentException("上午时段结束时间必须晚于开始时间");
                }
            }

            return true;

        } catch (Exception e) {
            throw new RuntimeException("设置验证失败: " + e.getMessage());
        }
    }

    // === 便捷方法：获取常用设置 ===

    public int getMaxReservationDays() {
        return getIntSetting("MAX_RESERVATION_DAYS", 7);
    }

    public int getMaxReservationHours() {
        return getIntSetting("MAX_RESERVATION_HOURS", 4);
    }

    public boolean isAllowCancelReservation() {
        return getBooleanSetting("ALLOW_CANCEL_RESERVATION", true);
    }

    public int getCancelDeadlineHours() {
        return getIntSetting("CANCEL_DEADLINE_HOURS", 2);
    }

    public String getSystemNotice() {
        return getSetting("SYSTEM_NOTICE");
    }

    public LocalTime getMorningStartTime() {
        return getTimeSetting("MORNING_START_TIME", LocalTime.of(8, 0));
    }

    public LocalTime getMorningEndTime() {
        return getTimeSetting("MORNING_END_TIME", LocalTime.of(12, 0));
    }

    public LocalTime getAfternoonStartTime() {
        return getTimeSetting("AFTERNOON_START_TIME", LocalTime.of(13, 0));
    }

    public LocalTime getAfternoonEndTime() {
        return getTimeSetting("AFTERNOON_END_TIME", LocalTime.of(17, 0));
    }

    public LocalTime getEveningStartTime() {
        return getTimeSetting("EVENING_START_TIME", LocalTime.of(18, 0));
    }

    public LocalTime getEveningEndTime() {
        return getTimeSetting("EVENING_END_TIME", LocalTime.of(22, 0));
    }

    // === 聚合设置获取方法 ===

    /**
     * 获取预约设置的聚合对象
     */
    public ReservationSettings getReservationSettings() {
        return new ReservationSettings(
                getMaxReservationDays(),
                getMaxReservationHours(),
                isAllowCancelReservation(),
                getCancelDeadlineHours());
    }

    /**
     * 获取时间段设置的聚合对象
     */
    public TimeSlotSettings getTimeSlotSettings() {
        return new TimeSlotSettings(
                getMorningStartTime(), getMorningEndTime(),
                getAfternoonStartTime(), getAfternoonEndTime(),
                getEveningStartTime(), getEveningEndTime());
    }

    // === 内部类定义 ===

    /**
     * 预约设置封装类
     */
    public static class ReservationSettings {
        private final int maxReservationDays;
        private final int maxReservationHours;
        private final boolean allowCancelReservation;
        private final int cancelDeadlineHours;

        public ReservationSettings(int maxReservationDays, int maxReservationHours,
                boolean allowCancelReservation, int cancelDeadlineHours) {
            this.maxReservationDays = maxReservationDays;
            this.maxReservationHours = maxReservationHours;
            this.allowCancelReservation = allowCancelReservation;
            this.cancelDeadlineHours = cancelDeadlineHours;
        }

        public int getMaxReservationDays() {
            return maxReservationDays;
        }

        public int getMaxReservationHours() {
            return maxReservationHours;
        }

        public boolean isAllowCancelReservation() {
            return allowCancelReservation;
        }

        public int getCancelDeadlineHours() {
            return cancelDeadlineHours;
        }
    }

    /**
     * 时间段设置封装类
     */
    public static class TimeSlotSettings {
        private final LocalTime morningStart;
        private final LocalTime morningEnd;
        private final LocalTime afternoonStart;
        private final LocalTime afternoonEnd;
        private final LocalTime eveningStart;
        private final LocalTime eveningEnd;

        public TimeSlotSettings(LocalTime morningStart, LocalTime morningEnd,
                LocalTime afternoonStart, LocalTime afternoonEnd,
                LocalTime eveningStart, LocalTime eveningEnd) {
            this.morningStart = morningStart;
            this.morningEnd = morningEnd;
            this.afternoonStart = afternoonStart;
            this.afternoonEnd = afternoonEnd;
            this.eveningStart = eveningStart;
            this.eveningEnd = eveningEnd;
        }

        public LocalTime getMorningStart() {
            return morningStart;
        }

        public LocalTime getMorningEnd() {
            return morningEnd;
        }

        public LocalTime getAfternoonStart() {
            return afternoonStart;
        }

        public LocalTime getAfternoonEnd() {
            return afternoonEnd;
        }

        public LocalTime getEveningStart() {
            return eveningStart;
        }

        public LocalTime getEveningEnd() {
            return eveningEnd;
        }
    }

    // === 私有辅助方法 ===

    private boolean shouldRefreshCache() {
        return System.currentTimeMillis() - lastCacheUpdate > CACHE_TIMEOUT;
    }

    private void refreshCache() throws SQLException {
        settingsCache = systemSettingsDAO.getAllSettings();
        lastCacheUpdate = System.currentTimeMillis();
    }

    private void loadHardcodedDefaults() {
        settingsCache.put("MAX_RESERVATION_DAYS", "7");
        settingsCache.put("MAX_RESERVATION_HOURS", "4");
        settingsCache.put("ALLOW_CANCEL_RESERVATION", "true");
        settingsCache.put("CANCEL_DEADLINE_HOURS", "2");
        settingsCache.put("MORNING_START_TIME", "08:00");
        settingsCache.put("MORNING_END_TIME", "12:00");
        settingsCache.put("AFTERNOON_START_TIME", "13:00");
        settingsCache.put("AFTERNOON_END_TIME", "17:00");
        settingsCache.put("EVENING_START_TIME", "18:00");
        settingsCache.put("EVENING_END_TIME", "22:00");
        settingsCache.put("SYSTEM_NOTICE", "欢迎使用自习室座位预约系统！\n请遵守自习室规章制度，保持安静学习环境。");
        lastCacheUpdate = System.currentTimeMillis();
    }
}
